//
//  PolygonSprite.m
//  CutCut
//
//  Created by Bullet Hermit on 12-11-2.
//  Copyright 2012年 紫竹飞燕. All rights reserved.
//

#import "PolygonSprite.h"
#import "Helper.h"

@implementation PolygonSprite
@synthesize body = _body;
@synthesize centroid = _centroid;
@synthesize isOriginal = _isOriginal;
@synthesize isSliceEntered = _isSliceEntered;
@synthesize isSliceExited = _isSliceExited;
@synthesize entryPoint = _entryPoint;
@synthesize exitPoint = _exitPoint;
@synthesize sliceEntryTime = _sliceEntryTime;
@synthesize state = _state;
@synthesize type = _type;
@synthesize splurt = _splurt;

+(id) spriteWithFile:(NSString *)filename body :(b2Body *)body original:(BOOL)isOriginal
{
    return [[[self alloc] initWithFile:filename body:body original:isOriginal] autorelease];
}
+(id) spriteWithTexture:(CCTexture2D *)texture body:(b2Body *)body original:(BOOL)isOriginal
{
    return [[[self alloc] initWithTexture:texture body:body original:isOriginal] autorelease];
}
+(id) spriteWithWorld:(b2World *)world
{
    return [[[self alloc] initWithWorld:world] autorelease];
}
-(id) initWithFile:(NSString *)filename body:(b2Body *)body original:(BOOL)isOriginal
{
    NSAssert(filename!= nil, @"file name cann't be null");
    CCTexture2D* texture = [[CCTextureCache sharedTextureCache] addImage:filename];
    return [self initWithTexture:texture body:body original:isOriginal];
}
-(id) initWithTexture:(CCTexture2D *)texture body:(b2Body *)body original:(BOOL)isOriginal
{
    //get all points to init self
    b2Fixture* fixture = body->GetFixtureList();
    b2PolygonShape* shape = (b2PolygonShape*)fixture->GetShape();
    int vertexCount = shape->GetVertexCount();
    NSMutableArray* points = [NSMutableArray arrayWithCapacity:vertexCount];
    for(int i = 0; i!=vertexCount;++i)
    {
        CGPoint p = ccp(shape->GetVertex(i ).x*PTM_RATIO,shape->GetVertex(i ).y*PTM_RATIO);
        [points addObject:[NSValue valueWithCGPoint:p]];
    }
    //init by the texture and points
    if(self = [super initWithPoints:points andTexture:texture])
    {
        //init slice attribute
        _sliceEntryTime = 0;
        _isSliceEntered = NO;
        _isSliceExited = NO;
        _entryPoint.SetZero();
        _exitPoint.SetZero();
        //init physic message
        _body = body;
        _body->SetUserData(self);
        _isOriginal = isOriginal;
        _centroid = self.body->GetLocalCenter();
        _state = kStateIdle;
        self.anchorPoint = ccp(_centroid.x * PTM_RATIO / texture.contentSize.width, _centroid.y * PTM_RATIO / texture.contentSize.height);
    }
    return self;
}

-(id) initWithWorld:(b2World *)world
{
    return nil;
}
-(void) setPosition:(CGPoint)position
{
    [super setPosition:position];
    _body->SetTransform([Helper toMeters:position], 0);
}
-(b2Body*) createBodyForWorld:(b2World *)world position:(b2Vec2)position rotation:(float)rotation vertices:(b2Vec2*)vertices vertexCount:(int32)count density:(float)density friction:(float)friction restitution:(float)restitution
{
    b2BodyDef bodyDef;
    bodyDef.position = position;
    bodyDef.type = b2_dynamicBody;
    bodyDef.angle = rotation;
    b2Body* body = world->CreateBody(&bodyDef);
    
    b2FixtureDef fixtureDef;
    fixtureDef.density = density;
    fixtureDef.friction = friction;
    fixtureDef.restitution = restitution;
    fixtureDef.isSensor = YES;
    fixtureDef.filter.maskBits = 0;
    fixtureDef.filter.categoryBits = 0;
    
    b2PolygonShape shape;
    shape.Set(vertices, count);
    fixtureDef.shape = &shape;
    body->CreateFixture(&fixtureDef);
    return body;
}
-(void) activeCollisions
{
    b2Fixture* fixture = _body->GetFixtureList();
    b2Filter filter = fixture->GetFilterData();
    filter.maskBits = 0x1;
    filter.categoryBits = 0x1;
    fixture->SetFilterData(filter);
}
-(void) deactiveCollisions
{
    b2Fixture* fixture = _body->GetFixtureList();
    b2Filter filter = fixture->GetFilterData();
    filter.maskBits = 0;
    filter.categoryBits = 0;
    fixture->SetFilterData(filter);
}
-(CGAffineTransform) nodeToParentTransform
{	
	b2Vec2 pos  = _body->GetPosition();
	
	float x = pos.x * PTM_RATIO;
	float y = pos.y * PTM_RATIO;
	
	if ( ignoreAnchorPointForPosition_ ) {
		x += anchorPointInPoints_.x;
		y += anchorPointInPoints_.y;
	}
	
	// Make matrix
	float radians = _body->GetAngle();
	float c = cosf(radians);
	float s = sinf(radians);
	
	if( ! CGPointEqualToPoint(anchorPointInPoints_, CGPointZero) ){
		x += c*-anchorPointInPoints_.x + -s*-anchorPointInPoints_.y;
		y += s*-anchorPointInPoints_.x + c*-anchorPointInPoints_.y;
	}
	
	// Rot, Translate Matrix
	transform_ = CGAffineTransformMake( c,  s,
									   -s,	c,
									   x,	y );	
	
	return transform_;
}
@end
